#ifndef MEMORYMAP_H
#define MEMORYMAP_H

#include <Globals.h>
#include <OrderedArray.h>
#include <Lockable.h>

/**
  Stores the layout of memory for a virtual memory space.
**/
class MemoryMap : public Lockable
{
public:
  /**
    The type of a mapping. Global is for kernel space and other such regions
    which are not destroyed on fork or exit.
    Local is for regions which should be destroyed on fork and exit.
    Mmap is for memory-mapped files etc which should survive across forks and die on exit.
  **/
  enum MapType {Any, Global, Local, Mmap};
  
  /**
    A type to describe a region of memory.
  **/
  typedef struct
  {
    Address start;
    Address length;
    MapType type;
  } MemoryRegion;
  
  MemoryMap();
  ~MemoryMap();
  
  /**
    Returns the address of a region of length 'length'. The region does
    not have any frames allocated. If higherThan != 0, the returned region will have
    a starting address higher than it.
  **/
  Address allocateRegion(Address length, MapType type, Address higherThan=0);
  
  /**
    Unmaps a region allocated with allocateRegion() or map().
  **/
  void deallocateRegion(Address addr);
  
  /**
    Maps a region at exactly the address specified with exactly that length.
    Returns false on failure. No frames are allocated.
  **/
  bool map(Address addr, Address length, MapType type);
  
  /**
    Creates a copy of itself.
  **/
  void clone(MemoryMap *other);
  
  /**
    Sets an internal iterator to the first region of type 'type', and returns that object.
  **/
  MemoryRegion *iterateFirst(MapType type);
  
  /**
    Advances the internal iterator.
  **/
  MemoryRegion *iterateNext(MapType type);
  
  /**
    Returns true if the iterator is currently valid.
  **/
  bool iterateIsValid();
  
  void dump();
  
private:
  typedef OrderedArray<MemoryRegion*,256> RegionArray;
  RegionArray regions;
  
  u32int iterator;
};

#endif
